package com.vogue.api.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.vogue.api.data.ResultVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Oauth2 授权管理
 */
@Slf4j
@Api(value = "ImOauth2", tags = "IM Oauth2授权管理接口")
@RestController
@RequestMapping("/api/oauth")
public class Oauth2Controller {
    protected Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private TokenEndpoint tokenEndpoint;

    /**
     * 1、获取access_token请求（/oauth/token）
     * 请求所需参数：client_id、client_secret、grant_type、username、password
     * grant_type=password：username、password必传
     * grant_type=wechat_mini：code（微信临时code）、userInfo(微信获取的)必传
     * grant_type=sms：smscode（短信验证码）、mobile必传
     *
     * 2、刷新token请求（/oauth/token）
     * 请求所需参数：grant_type、refresh_token、client_id、client_secret
     * 其中grant_type为固定值：grant_type=refresh_token
     *
     * @param principal
     * @param parameters
     * @return
     * @throws HttpRequestMethodNotSupportedException
     */
    @RequestMapping(value = "/token", method = {RequestMethod.GET,RequestMethod.POST})
    public ResultVo getAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        logger.error(JSONObject.toJSONString(parameters));

        DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) tokenEndpoint.getAccessToken(principal, parameters).getBody();
        Map<String, Object> data = new LinkedHashMap(token.getAdditionalInformation());

        logger.error(JSONObject.toJSONString(token));

        data.put("access_token", token.getValue());
        data.put("scope", token.getScope());
        data.put("token_type", token.getTokenType());

        if (token.getRefreshToken() != null) {
            data.put("refresh_token", token.getRefreshToken().getValue());
            data.put("expiration", token.getExpiration().getTime());//过期时间
        }
        logger.error(JSONObject.toJSONString(ResultVo.success(data)));
        return ResultVo.success(data);
    }
    /**
     * 退出并删除token
     * @param authHeader Authorization
     */
    @RequestMapping(value = "/logout", method = {RequestMethod.GET,RequestMethod.POST})
    public ResultVo logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
        if (StrUtil.isBlank(authHeader)) {
            return ResultVo.success();
        }
        String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim();
        OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
        if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
            return ResultVo.success();
        }
        // 清空 refresh token
        OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
        tokenStore.removeRefreshToken(refreshToken);
        // 清空access token
        tokenStore.removeAccessToken(accessToken);

        return ResultVo.success();
    }
}
